/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package n64Controller;

import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import n64Controller.N64Controller.ButtonEvent;
import n64Controller.N64Controller.MoveEvent;

/**
 *
 * @author marcos
 */
public class N64CImagePanel extends javax.swing.JPanel {
    
    private BufferedImage image;
    private boolean waitingInput = false;
    private N64Controller.Button button;
    private N64Controller controller;
    private KeyEventDispatcherSourceChanger dispatcher;

    /**
     * Creates new form N64KeysPanel
     */
    public N64CImagePanel() {
        loadImage();
        initComponents();
        dispatcher = new KeyEventDispatcherSourceChanger(this);
        try {
            controller = new N64Controller();
            controller.addEventListener(new N64Controller.N64ControllerEventListener() {
                
                @Override
                public void buttonPressed(ButtonEvent evt) {
                    ((JButton) find(evt.button.name())).setBorderPainted(true);
                }
                
                @Override
                public void buttonReleased(ButtonEvent evt) {
                    ((JButton) find(evt.button.name())).setBorderPainted(false);
                }
                
                @Override
                public void moved(MoveEvent evt) {
                    Point analogValue = ((N64Controller) evt.getSource()).applyDeadZone(evt.analogValue);
                    bordersAnalog(analogValue);
                }
            });
        } catch (AWTException ex) {
            Logger.getLogger(N64CImagePanel.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    public Component find(String name) {
        Component[] components = getComponents();
        for (Component c : components) {
            if (c.getName().equals(name)) {
                return c;
            }
        }
        return null;
    }
    
    private void bordersAnalog(Point analogValue) {
        if (analogValue.y > 0) {
            jButtonA_DOWN.setBorderPainted(false);
            jButtonA_UP.setBorderPainted(true);
        } else if (analogValue.y < 0) {
            jButtonA_UP.setBorderPainted(false);
            jButtonA_DOWN.setBorderPainted(true);
        } else {
            jButtonA_UP.setBorderPainted(false);
            jButtonA_DOWN.setBorderPainted(false);
        }
        
        if (analogValue.x > 0) {
            jButtonA_LEFT.setBorderPainted(false);
            jButtonA_RIGHT.setBorderPainted(true);
        } else if (analogValue.x < 0) {
            jButtonA_RIGHT.setBorderPainted(false);
            jButtonA_LEFT.setBorderPainted(true);
        } else {
            jButtonA_RIGHT.setBorderPainted(false);
            jButtonA_LEFT.setBorderPainted(false);
        }
    }
    
    @Override
    protected void paintComponent(Graphics g) {
        g.drawImage(image, 0, 0, null);
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jTextFieldStatus = new javax.swing.JTextField();
        jButtonSTART = new javax.swing.JButton();
        jButtonD_UP = new javax.swing.JButton();
        jButtonD_DOWN = new javax.swing.JButton();
        jButtonD_LEFT = new javax.swing.JButton();
        jButtonD_RIGHT = new javax.swing.JButton();
        jButtonA_UP = new javax.swing.JButton();
        jButtonA_DOWN = new javax.swing.JButton();
        jButtonA_LEFT = new javax.swing.JButton();
        jButtonA_RIGHT = new javax.swing.JButton();
        jButtonC_UP = new javax.swing.JButton();
        jButtonC_DOWN = new javax.swing.JButton();
        jButtonC_LEFT = new javax.swing.JButton();
        jButtonC_RIGHT = new javax.swing.JButton();
        jButtonB = new javax.swing.JButton();
        jButtonA = new javax.swing.JButton();
        jButtonZ = new javax.swing.JButton();
        jButtonL = new javax.swing.JButton();
        jButtonR = new javax.swing.JButton();

        setName("Panel");
        setPreferredSize(new java.awt.Dimension(540, 300));
        addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                jButtonBAuttonMouseEntered(evt);
            }
        });
        addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                formKeyPressed(evt);
            }
        });
        setLayout(null);

        jTextFieldStatus.setBackground(new java.awt.Color(51, 51, 51));
        jTextFieldStatus.setColumns(22);
        jTextFieldStatus.setEditable(false);
        jTextFieldStatus.setForeground(new java.awt.Color(255, 255, 255));
        jTextFieldStatus.setHorizontalAlignment(javax.swing.JTextField.LEFT);
        jTextFieldStatus.setText("Click on a button and enter a key.");
        jTextFieldStatus.setName("Status");
        jTextFieldStatus.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                jButtonBAuttonMouseEntered(evt);
            }
        });
        jTextFieldStatus.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                formKeyPressed(evt);
            }
        });
        add(jTextFieldStatus);
        jTextFieldStatus.setBounds(10, 269, 182, 20);

        jButtonSTART.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 0, 204), 4, true));
        jButtonSTART.setBorderPainted(false);
        jButtonSTART.setContentAreaFilled(false);
        jButtonSTART.setFocusable(false);
        jButtonSTART.setMaximumSize(new java.awt.Dimension(20, 20));
        jButtonSTART.setMinimumSize(new java.awt.Dimension(20, 20));
        jButtonSTART.setName("START");
        jButtonSTART.setPreferredSize(new java.awt.Dimension(20, 20));
        jButtonSTART.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                jButtonBAuttonMouseEntered(evt);
            }
        });
        jButtonSTART.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonActionPerformed(evt);
            }
        });
        add(jButtonSTART);
        jButtonSTART.setBounds(260, 80, 30, 30);

        jButtonD_UP.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 0, 204), 4, true));
        jButtonD_UP.setBorderPainted(false);
        jButtonD_UP.setContentAreaFilled(false);
        jButtonD_UP.setFocusable(false);
        jButtonD_UP.setMaximumSize(new java.awt.Dimension(20, 20));
        jButtonD_UP.setMinimumSize(new java.awt.Dimension(20, 20));
        jButtonD_UP.setName("D_UP");
        jButtonD_UP.setPreferredSize(new java.awt.Dimension(20, 20));
        jButtonD_UP.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                jButtonBAuttonMouseEntered(evt);
            }
        });
        jButtonD_UP.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonActionPerformed(evt);
            }
        });
        add(jButtonD_UP);
        jButtonD_UP.setBounds(170, 60, 20, 20);

        jButtonD_DOWN.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 0, 204), 4, true));
        jButtonD_DOWN.setBorderPainted(false);
        jButtonD_DOWN.setContentAreaFilled(false);
        jButtonD_DOWN.setFocusable(false);
        jButtonD_DOWN.setMaximumSize(new java.awt.Dimension(20, 20));
        jButtonD_DOWN.setMinimumSize(new java.awt.Dimension(20, 20));
        jButtonD_DOWN.setName("D_DOWN");
        jButtonD_DOWN.setPreferredSize(new java.awt.Dimension(20, 20));
        jButtonD_DOWN.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                jButtonBAuttonMouseEntered(evt);
            }
        });
        jButtonD_DOWN.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonActionPerformed(evt);
            }
        });
        add(jButtonD_DOWN);
        jButtonD_DOWN.setBounds(170, 100, 20, 20);

        jButtonD_LEFT.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 0, 204), 4, true));
        jButtonD_LEFT.setBorderPainted(false);
        jButtonD_LEFT.setContentAreaFilled(false);
        jButtonD_LEFT.setFocusable(false);
        jButtonD_LEFT.setMaximumSize(new java.awt.Dimension(20, 20));
        jButtonD_LEFT.setMinimumSize(new java.awt.Dimension(20, 20));
        jButtonD_LEFT.setName("D_LEFT");
        jButtonD_LEFT.setPreferredSize(new java.awt.Dimension(20, 20));
        jButtonD_LEFT.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                jButtonBAuttonMouseEntered(evt);
            }
        });
        jButtonD_LEFT.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonActionPerformed(evt);
            }
        });
        add(jButtonD_LEFT);
        jButtonD_LEFT.setBounds(150, 80, 20, 20);

        jButtonD_RIGHT.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 0, 204), 4, true));
        jButtonD_RIGHT.setBorderPainted(false);
        jButtonD_RIGHT.setContentAreaFilled(false);
        jButtonD_RIGHT.setFocusable(false);
        jButtonD_RIGHT.setMaximumSize(new java.awt.Dimension(20, 20));
        jButtonD_RIGHT.setMinimumSize(new java.awt.Dimension(20, 20));
        jButtonD_RIGHT.setName("D_RIGHT");
        jButtonD_RIGHT.setPreferredSize(new java.awt.Dimension(20, 20));
        jButtonD_RIGHT.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                jButtonBAuttonMouseEntered(evt);
            }
        });
        jButtonD_RIGHT.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonActionPerformed(evt);
            }
        });
        add(jButtonD_RIGHT);
        jButtonD_RIGHT.setBounds(190, 80, 20, 20);

        jButtonA_UP.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 0, 204), 4, true));
        jButtonA_UP.setBorderPainted(false);
        jButtonA_UP.setContentAreaFilled(false);
        jButtonA_UP.setFocusable(false);
        jButtonA_UP.setMaximumSize(new java.awt.Dimension(20, 20));
        jButtonA_UP.setMinimumSize(new java.awt.Dimension(20, 20));
        jButtonA_UP.setName("A_UP");
        jButtonA_UP.setPreferredSize(new java.awt.Dimension(20, 20));
        jButtonA_UP.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                jButtonBAuttonMouseEntered(evt);
            }
        });
        jButtonA_UP.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonActionPerformed(evt);
            }
        });
        add(jButtonA_UP);
        jButtonA_UP.setBounds(260, 110, 30, 40);

        jButtonA_DOWN.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 0, 204), 4, true));
        jButtonA_DOWN.setBorderPainted(false);
        jButtonA_DOWN.setContentAreaFilled(false);
        jButtonA_DOWN.setFocusable(false);
        jButtonA_DOWN.setMaximumSize(new java.awt.Dimension(20, 20));
        jButtonA_DOWN.setMinimumSize(new java.awt.Dimension(20, 20));
        jButtonA_DOWN.setName("A_DOWN");
        jButtonA_DOWN.setPreferredSize(new java.awt.Dimension(20, 20));
        jButtonA_DOWN.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                jButtonBAuttonMouseEntered(evt);
            }
        });
        jButtonA_DOWN.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonActionPerformed(evt);
            }
        });
        add(jButtonA_DOWN);
        jButtonA_DOWN.setBounds(250, 170, 30, 40);

        jButtonA_LEFT.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 0, 204), 4, true));
        jButtonA_LEFT.setBorderPainted(false);
        jButtonA_LEFT.setContentAreaFilled(false);
        jButtonA_LEFT.setFocusable(false);
        jButtonA_LEFT.setMaximumSize(new java.awt.Dimension(20, 20));
        jButtonA_LEFT.setMinimumSize(new java.awt.Dimension(20, 20));
        jButtonA_LEFT.setName("A_LEFT");
        jButtonA_LEFT.setPreferredSize(new java.awt.Dimension(20, 20));
        jButtonA_LEFT.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                jButtonBAuttonMouseEntered(evt);
            }
        });
        jButtonA_LEFT.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonActionPerformed(evt);
            }
        });
        add(jButtonA_LEFT);
        jButtonA_LEFT.setBounds(220, 140, 40, 30);

        jButtonA_RIGHT.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 0, 204), 4, true));
        jButtonA_RIGHT.setBorderPainted(false);
        jButtonA_RIGHT.setContentAreaFilled(false);
        jButtonA_RIGHT.setFocusable(false);
        jButtonA_RIGHT.setMaximumSize(new java.awt.Dimension(20, 20));
        jButtonA_RIGHT.setMinimumSize(new java.awt.Dimension(20, 20));
        jButtonA_RIGHT.setName("A_RIGHT");
        jButtonA_RIGHT.setPreferredSize(new java.awt.Dimension(20, 20));
        jButtonA_RIGHT.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                jButtonBAuttonMouseEntered(evt);
            }
        });
        jButtonA_RIGHT.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonActionPerformed(evt);
            }
        });
        add(jButtonA_RIGHT);
        jButtonA_RIGHT.setBounds(280, 150, 40, 30);

        jButtonC_UP.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 0, 204), 4, true));
        jButtonC_UP.setBorderPainted(false);
        jButtonC_UP.setContentAreaFilled(false);
        jButtonC_UP.setFocusable(false);
        jButtonC_UP.setMaximumSize(new java.awt.Dimension(20, 20));
        jButtonC_UP.setMinimumSize(new java.awt.Dimension(20, 20));
        jButtonC_UP.setName("C_UP");
        jButtonC_UP.setPreferredSize(new java.awt.Dimension(20, 20));
        jButtonC_UP.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                jButtonBAuttonMouseEntered(evt);
            }
        });
        jButtonC_UP.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonActionPerformed(evt);
            }
        });
        add(jButtonC_UP);
        jButtonC_UP.setBounds(360, 50, 20, 20);

        jButtonC_DOWN.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 0, 204), 4, true));
        jButtonC_DOWN.setBorderPainted(false);
        jButtonC_DOWN.setContentAreaFilled(false);
        jButtonC_DOWN.setFocusable(false);
        jButtonC_DOWN.setMaximumSize(new java.awt.Dimension(20, 20));
        jButtonC_DOWN.setMinimumSize(new java.awt.Dimension(20, 20));
        jButtonC_DOWN.setName("C_DOWN");
        jButtonC_DOWN.setPreferredSize(new java.awt.Dimension(20, 20));
        jButtonC_DOWN.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                jButtonBAuttonMouseEntered(evt);
            }
        });
        jButtonC_DOWN.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonActionPerformed(evt);
            }
        });
        add(jButtonC_DOWN);
        jButtonC_DOWN.setBounds(360, 90, 20, 20);

        jButtonC_LEFT.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 0, 204), 4, true));
        jButtonC_LEFT.setBorderPainted(false);
        jButtonC_LEFT.setContentAreaFilled(false);
        jButtonC_LEFT.setFocusable(false);
        jButtonC_LEFT.setMaximumSize(new java.awt.Dimension(20, 20));
        jButtonC_LEFT.setMinimumSize(new java.awt.Dimension(20, 20));
        jButtonC_LEFT.setName("C_LEFT");
        jButtonC_LEFT.setPreferredSize(new java.awt.Dimension(20, 20));
        jButtonC_LEFT.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                jButtonBAuttonMouseEntered(evt);
            }
        });
        jButtonC_LEFT.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonActionPerformed(evt);
            }
        });
        add(jButtonC_LEFT);
        jButtonC_LEFT.setBounds(340, 70, 20, 20);

        jButtonC_RIGHT.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 0, 204), 4, true));
        jButtonC_RIGHT.setBorderPainted(false);
        jButtonC_RIGHT.setContentAreaFilled(false);
        jButtonC_RIGHT.setFocusable(false);
        jButtonC_RIGHT.setMaximumSize(new java.awt.Dimension(20, 20));
        jButtonC_RIGHT.setMinimumSize(new java.awt.Dimension(20, 20));
        jButtonC_RIGHT.setName("C_RIGHT");
        jButtonC_RIGHT.setPreferredSize(new java.awt.Dimension(20, 20));
        jButtonC_RIGHT.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                jButtonBAuttonMouseEntered(evt);
            }
        });
        jButtonC_RIGHT.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonActionPerformed(evt);
            }
        });
        add(jButtonC_RIGHT);
        jButtonC_RIGHT.setBounds(380, 70, 20, 20);

        jButtonB.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 0, 204), 4, true));
        jButtonB.setBorderPainted(false);
        jButtonB.setContentAreaFilled(false);
        jButtonB.setFocusable(false);
        jButtonB.setMaximumSize(new java.awt.Dimension(20, 20));
        jButtonB.setMinimumSize(new java.awt.Dimension(20, 20));
        jButtonB.setName("B");
        jButtonB.setPreferredSize(new java.awt.Dimension(20, 20));
        jButtonB.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                jButtonBAuttonMouseEntered(evt);
            }
        });
        jButtonB.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonActionPerformed(evt);
            }
        });
        add(jButtonB);
        jButtonB.setBounds(320, 90, 20, 20);

        jButtonA.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 0, 204), 4, true));
        jButtonA.setBorderPainted(false);
        jButtonA.setContentAreaFilled(false);
        jButtonA.setFocusable(false);
        jButtonA.setMaximumSize(new java.awt.Dimension(20, 20));
        jButtonA.setMinimumSize(new java.awt.Dimension(20, 20));
        jButtonA.setName("A");
        jButtonA.setPreferredSize(new java.awt.Dimension(20, 20));
        jButtonA.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                jButtonBAuttonMouseEntered(evt);
            }
        });
        jButtonA.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonActionPerformed(evt);
            }
        });
        add(jButtonA);
        jButtonA.setBounds(340, 110, 20, 20);

        jButtonZ.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 0, 204), 4, true));
        jButtonZ.setBorderPainted(false);
        jButtonZ.setContentAreaFilled(false);
        jButtonZ.setFocusable(false);
        jButtonZ.setMaximumSize(new java.awt.Dimension(20, 40));
        jButtonZ.setMinimumSize(new java.awt.Dimension(20, 40));
        jButtonZ.setName("Z");
        jButtonZ.setPreferredSize(new java.awt.Dimension(20, 40));
        jButtonZ.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                jButtonBAuttonMouseEntered(evt);
            }
        });
        jButtonZ.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonActionPerformed(evt);
            }
        });
        add(jButtonZ);
        jButtonZ.setBounds(455, 204, 55, 72);

        jButtonL.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 0, 204), 4, true));
        jButtonL.setBorderPainted(false);
        jButtonL.setContentAreaFilled(false);
        jButtonL.setFocusable(false);
        jButtonL.setMaximumSize(new java.awt.Dimension(40, 20));
        jButtonL.setMinimumSize(new java.awt.Dimension(40, 20));
        jButtonL.setName("L");
        jButtonL.setPreferredSize(new java.awt.Dimension(40, 20));
        jButtonL.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                jButtonBAuttonMouseEntered(evt);
            }
        });
        jButtonL.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonActionPerformed(evt);
            }
        });
        add(jButtonL);
        jButtonL.setBounds(150, 20, 60, 30);

        jButtonR.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 0, 204), 4, true));
        jButtonR.setBorderPainted(false);
        jButtonR.setContentAreaFilled(false);
        jButtonR.setFocusable(false);
        jButtonR.setMaximumSize(new java.awt.Dimension(40, 20));
        jButtonR.setMinimumSize(new java.awt.Dimension(40, 20));
        jButtonR.setName("R");
        jButtonR.setPreferredSize(new java.awt.Dimension(40, 20));
        jButtonR.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                jButtonBAuttonMouseEntered(evt);
            }
        });
        jButtonR.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonActionPerformed(evt);
            }
        });
        add(jButtonR);
        jButtonR.setBounds(330, 20, 70, 30);
    }// </editor-fold>//GEN-END:initComponents

    private void jButtonBAuttonMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jButtonBAuttonMouseEntered
        if (waitingInput) {
            return;
        }
        if (evt.getComponent() instanceof JButton) {
            int keyCode = controller.getKey(evt.getComponent().getName());
            jTextFieldStatus.setText("Current key for " + evt.getComponent().getName() + ": " + KeyEvent.getKeyText(keyCode));
        } else {
            jTextFieldStatus.setText("Click on a button and enter a key.");
        }
    }//GEN-LAST:event_jButtonBAuttonMouseEntered
    
    private void jButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonActionPerformed
        if (waitingInput) {
            return;
        }
        waitKeyInput(N64Controller.Button.valueOf(((Component) evt.getSource()).getName()));
    }//GEN-LAST:event_jButtonActionPerformed
    
    private void formKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_formKeyPressed
        if (!waitingInput) { // http://stackoverflow.com/questions/4780910/jpanel-keylistener
            return;
        }
        if (evt.getKeyCode() == KeyEvent.VK_ESCAPE) {
            jTextFieldStatus.setText("Cancelled.");
        } else {
            jTextFieldStatus.setText("Changed to key: " + KeyEvent.getKeyText(evt.getKeyCode()));
            controller.setKey(button, evt.getKeyCode());
        }
        removeDispatcher();
        waitingInput = false;
    }//GEN-LAST:event_formKeyPressed
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButtonA;
    private javax.swing.JButton jButtonA_DOWN;
    private javax.swing.JButton jButtonA_LEFT;
    private javax.swing.JButton jButtonA_RIGHT;
    private javax.swing.JButton jButtonA_UP;
    private javax.swing.JButton jButtonB;
    private javax.swing.JButton jButtonC_DOWN;
    private javax.swing.JButton jButtonC_LEFT;
    private javax.swing.JButton jButtonC_RIGHT;
    private javax.swing.JButton jButtonC_UP;
    private javax.swing.JButton jButtonD_DOWN;
    private javax.swing.JButton jButtonD_LEFT;
    private javax.swing.JButton jButtonD_RIGHT;
    private javax.swing.JButton jButtonD_UP;
    private javax.swing.JButton jButtonL;
    private javax.swing.JButton jButtonR;
    private javax.swing.JButton jButtonSTART;
    private javax.swing.JButton jButtonZ;
    private javax.swing.JTextField jTextFieldStatus;
    // End of variables declaration//GEN-END:variables

    private void loadImage() {
        try {
            image = ImageIO.read(new File("N64Controller.jpg"));
        } catch (IOException ex) {
            Logger.getLogger(N64CImagePanel.class.getName()).log(Level.SEVERE, null, ex);
        }
        Dimension size;
        if (image != null) {
            size = new Dimension(image.getWidth(null), image.getHeight(null));
        } else {
            size = new Dimension(540, 300);
        }
        
        setPreferredSize(size);
        setMinimumSize(size);
        setMaximumSize(size);
    }
    
    private void waitKeyInput(N64Controller.Button b) {
        jTextFieldStatus.setText("Waiting key for " + b);
        addDispatcher();
        waitingInput = true;
        button = b;
    }
    
    private void addDispatcher() {
        KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(dispatcher);
    }
    
    private void removeDispatcher() {
        KeyboardFocusManager.getCurrentKeyboardFocusManager().removeKeyEventDispatcher(dispatcher);
    }
    
    public N64Controller getController() {
        return controller;
    }
    
    protected static class KeyEventDispatcherSourceChanger implements KeyEventDispatcher {
        
        private Object o;
        
        public KeyEventDispatcherSourceChanger(Object o) {
            this.o = o;
        }
        
        @Override
        public boolean dispatchKeyEvent(KeyEvent e) {
            e.setSource(o);
            return false;
        }
    }
}
